home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Best of Down Under Games
/
The Best of Down Under Games.iso
/
3dfx Screen Savers
/
Power Render
/
SRC.ZIP
/
WINUTIL.C
< prev
Wrap
C/C++ Source or Header
|
1997-07-10
|
15KB
|
704 lines
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <assert.h>
#if defined(MSGLIDE) || defined (WTGLIDE)
#include <glide.h>
#endif
#include <dinput.h>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <windowsx.h>
#include "winutil.h"
#define TITLE "Egerter Software 3Dfx ScreenSaver"
/* Forward declarations */
HWND hWndMain;
HINSTANCE hInstance; /* My instance handle */
char ** commandLineToArgv(LPSTR lpCmdLine, int *pArgc);
void PRGUI_InitPath (char *startpath);
/* The following variables are used to simulate the input routines
from WGT 5.1 */
char kbdon[256];
static int keyhead = 0;
static int keytail = 0;
static int keyqueue[256] = {0};
PR_MouseCallback_data mouse;
int PR_mx0, PR_my0, PR_mx1, PR_my1;
/* Direct Input */
#define WM_SYNCACQUIRE (WM_USER + 0)
LPDIRECTINPUT g_pdi = NULL;
LPDIRECTINPUTDEVICE g_pMouse;
LPDIRECTINPUTDEVICE g_pKeyboard;
HANDLE g_hevtMouse;
int PR_AppActive;
int fKeybdAcquired;
int minit (void)
{
HRESULT err;
GUID guid = GUID_SysMouse;
if (g_pdi == NULL)
{
err = DirectInputCreate(hInstance, DIRECTINPUT_VERSION, &g_pdi, NULL);
if(FAILED(err))
{
MessageBox(NULL, "Unable to Create DirectInput Object",
TITLE, MB_OK);
return FALSE;
}
}
/* Obtain an interface to the system mouse device. */
err = g_pdi->lpVtbl->CreateDevice(g_pdi, &guid, &g_pMouse, NULL);
if (FAILED(err))
{
MessageBox(NULL, "Unable to Create DirectInput Mouse Device",
TITLE, MB_OK);
return FALSE;
}
/* Set the data format to "mouse format". */
err = g_pMouse->lpVtbl->SetDataFormat(g_pMouse, &c_dfDIMouse);
if (FAILED(err))
{
MessageBox(NULL, "Unable to Set Mouse Format",
TITLE, MB_OK);
return FALSE;
}
/* Set the cooperativity level. */
err = g_pMouse->lpVtbl->SetCooperativeLevel(g_pMouse, hWndMain,
DISCL_EXCLUSIVE | DISCL_FOREGROUND);
if (FAILED(err))
{
MessageBox(NULL, "Unable to Set Cooperative Level",
TITLE, MB_OK);
return FALSE;
}
PR_mx0 = 0;
PR_my0 = 0;
PR_mx1 = 639;
PR_my1 = 479;
mouse.mx = 320;
mouse.my = 240;
mouse.but = 0;
return TRUE;
}
void mdeinit (void)
{
if (g_pdi) g_pdi ->lpVtbl->Release(g_pdi), g_pdi = NULL;
if (g_pMouse) g_pMouse->lpVtbl->Release(g_pMouse), g_pMouse = NULL;
}
void msetbounds (int x0, int y0, int x1, int y1)
{
PR_mx0 = x0;
PR_my0 = y0;
PR_mx1 = x1;
PR_my1 = y1;
}
void msetxy (int x0, int y0)
{
mouse.mx = x0;
mouse.my = y0;
}
void noclick (void)
{
while (mouse.but)
UpdateMessages ();
}
void PR_ReadMouse (void)
{
DIMOUSESTATE diMouseState;
if (PR_AppActive)
{
if (g_pMouse->lpVtbl->GetDeviceState(g_pMouse,
sizeof(diMouseState), &diMouseState) == DI_OK)
{
mouse.mx += (int)diMouseState.lX;
mouse.my += (int)diMouseState.lY;
mouse.but = (diMouseState.rgbButtons[0]>0) +
((diMouseState.rgbButtons[1]>0)<<1) +
((diMouseState.rgbButtons[2]>0)<<2);
}
}
/* Clip the cursor to our client area */
if (mouse.mx < PR_mx0)
mouse.mx = PR_mx0;
if (mouse.mx > PR_mx1)
mouse.mx = PR_mx1;
if (mouse.my < PR_my0)
mouse.my = PR_my0;
if (mouse.my > PR_my1)
mouse.my = PR_my1;
}
void PR_MouseSyncAcquire (HWND hwnd)
{
if (PR_AppActive) {
if (g_pMouse)
g_pMouse->lpVtbl->Acquire(g_pMouse);
} else {
if (g_pMouse)
g_pMouse->lpVtbl->Unacquire(g_pMouse);
}
// InvalidateCursorRect(hwnd);
}
int installkbd (void)
{
GUID guid = GUID_SysKeyboard;
HRESULT err;
if (g_pdi == NULL)
{
err = DirectInputCreate(hInstance, DIRECTINPUT_VERSION, &g_pdi, NULL);
if(FAILED(err))
{
MessageBox(NULL, "Unable to Create DirectInput Object",
TITLE, MB_OK);
return FALSE;
}
}
/* Obtain an interface to the system mouse device. */
err = g_pdi->lpVtbl->CreateDevice(g_pdi, &guid, &g_pKeyboard, NULL);
if (FAILED(err))
{
MessageBox(NULL, "Unable to Create DirectInput Keyboard Device",
TITLE, MB_OK);
return FALSE;
}
/* Set the data format to "mouse format". */
err = g_pKeyboard->lpVtbl->SetDataFormat(g_pKeyboard, &c_dfDIKeyboard);
if (FAILED(err))
{
MessageBox(NULL, "Unable to Set Keyboard Format",
TITLE, MB_OK);
return FALSE;
}
/* Set the cooperativity level. */
err = g_pKeyboard->lpVtbl->SetCooperativeLevel(g_pKeyboard, hWndMain,
DISCL_NONEXCLUSIVE | DISCL_FOREGROUND);
if (FAILED(err))
{
MessageBox(NULL, "Unable to Set Keyboard Cooperative Level",
TITLE, MB_OK);
return FALSE;
}
// try to acquire the keyboard
err = g_pKeyboard->lpVtbl->Acquire(g_pKeyboard);
if(SUCCEEDED(err))
{
// keyboard was acquired
fKeybdAcquired = TRUE;
}
else
{
// keyboard was NOT acquired
fKeybdAcquired = FALSE;
}
// if we get here, all objects were created successfully
return TRUE;
}
/*
*
* DI_ReadKeys
*
* Use DirectInput to read game-play keys
*
*/
void PR_ReadKeyboard(void)
{
HRESULT hRes;
if (g_pKeyboard == NULL)
return;
hRes = g_pKeyboard->lpVtbl->GetDeviceState(g_pKeyboard, sizeof(kbdon), kbdon);
if(hRes != DI_OK)
{
if(hRes == DIERR_INPUTLOST)
{
// we lost control of the keyboard, reacquire
fKeybdAcquired = FALSE;
if(SUCCEEDED(g_pKeyboard->lpVtbl->Acquire(g_pKeyboard)))
{
fKeybdAcquired = TRUE;
}
}
// failed to read the keyboard, just return
return;
}
}
void uninstallkbd (void)
{
if(fKeybdAcquired)
{
g_pKeyboard->lpVtbl->Unacquire(g_pKeyboard);
fKeybdAcquired = FALSE;
}
if(g_pKeyboard != NULL)
g_pKeyboard->lpVtbl->Release(g_pKeyboard);
g_pKeyboard = NULL;
}
BOOL PR_KeyboardSyncAcquire (void)
{
// try to acquire the keyboard
if(g_pKeyboard != NULL)
{
g_pKeyboard->lpVtbl->Acquire(g_pKeyboard);
}
else
{
// keyboard device has not been created.
fKeybdAcquired = FALSE;
return FALSE;
}
// if we get here, we are acquired again
fKeybdAcquired = TRUE;
return TRUE;
}
long FAR PASCAL MainWndproc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
PAINTSTRUCT ps;
HDC hdc;
LRESULT lRc;
switch( message )
{
case WM_SETCURSOR:
SetCursor(NULL);
return 0;
break;
case WM_KEYDOWN:
if(!fKeybdAcquired)
{
keyqueue[keyhead++] = wParam & 0xFF;
keyhead &= 255;
return 0;
}
break;
case WM_KEYUP:
return 0;
break;
case WM_ACTIVATE:
{
WORD fActive = LOWORD(wParam);
BOOL fMinimized = (BOOL) HIWORD(wParam);
if ( ( fActive == WA_INACTIVE ) || fMinimized )
{
#if defined(MSGLIDE) || defined(WTGLIDE)
grSstControl (GR_CONTROL_DEACTIVATE);
PR_AppActive = FALSE;
PR_MouseSyncAcquire (hWnd);
#endif
}
else
{
#if defined(MSGLIDE) || defined(WTGLIDE)
grSstControl (GR_CONTROL_ACTIVATE);
PR_AppActive = TRUE;
#endif
PR_MouseSyncAcquire(hWnd);
PR_KeyboardSyncAcquire();
SetForegroundWindow (hWnd);
}
}
break;
case WM_ENTERMENULOOP:
case WM_ENTERSIZEMOVE:
PR_AppActive = FALSE;
PR_MouseSyncAcquire(hWnd);
PR_KeyboardSyncAcquire();
break;
case WM_EXITMENULOOP:
case WM_EXITSIZEMOVE:
PR_AppActive = GetActiveWindow() == hWnd;
PostMessage(hWnd, WM_SYNCACQUIRE, 0, 0L);
break;
case WM_SYNCACQUIRE:
PR_MouseSyncAcquire (hWnd);
PR_KeyboardSyncAcquire();
break;
case WM_CREATE:
break;
case WM_PAINT:
hdc = BeginPaint( hWnd, &ps );
EndPaint( hWnd, &ps );
return 1;
case WM_CLOSE:
keyqueue[keyhead++] = 'q'; keyhead &= 255;
break;
case WM_DESTROY:
PostQuitMessage (0);
break;
case WM_MOVE:
#if defined(MSGLIDE) || defined(WTGLIDE)
if (!grSstControl(GR_CONTROL_MOVE)) {
PostMessage( hWnd, WM_CLOSE, 0, 0 );
return 0;
}
#endif
break;
case WM_SYSCOMMAND:
switch (GET_WM_COMMAND_ID(wParam, lParam)) {
case SC_SCREENSAVE:
break;
default:
lRc = DefWindowProc(hWnd, message, wParam, lParam);
break;
}
if (IsWindow(hWnd)) {
PR_MouseSyncAcquire (hWnd);
PR_KeyboardSyncAcquire();
}
return lRc;
case WM_DISPLAYCHANGE:
case WM_SIZE:
{
extern void getWindowSize(float *width, float *height);
float width, height;
getWindowSize(&width, &height);
}
#if defined(MSGLIDE) || defined(WTGLIDE)
if (!grSstControl(GR_CONTROL_RESIZE)) {
PostMessage(hWnd, WM_CLOSE, 0, 0 );
return 0;
}
#endif
break;
default:
break;
}
return DefWindowProc(hWnd, message, wParam, lParam);
} /* MainWndproc */
/*
* initApplication
*
* Do that Windows initialization stuff...
*/
void PRGUI_LoadCursor3Dx (void);
static BOOL initApplication( HANDLE hInstance, int nCmdShow )
{
WNDCLASS wc;
BOOL rc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = MainWndproc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon( NULL, IDI_APPLICATION); /* generic icon */
wc.hCursor = NULL; //LoadCursor( NULL, IDC_ARROW );
wc.hbrBackground = GetStockObject( BLACK_BRUSH );
wc.lpszMenuName = NULL;
wc.lpszClassName = "WinGlideClass";
rc = RegisterClass( &wc );
if( !rc )
{
return FALSE;
}
hWndMain = CreateWindowEx(
WS_EX_TOPMOST,
"WinGlideClass",
TITLE,
WS_OVERLAPPED |
WS_CAPTION |
WS_SYSMENU | /* so we get an icon in the tray */
WS_THICKFRAME |
WS_MAXIMIZEBOX |
WS_MINIMIZEBOX |
WS_VISIBLE, /* so we don't have to call ShowWindow */
//WS_POPUP | /* non-app window */
CW_USEDEFAULT,
CW_USEDEFAULT,
600, /* GetSystemMetrics(SM_CXSCREEN), */
40, /* GetSystemMetrics(SM_CYSCREEN), */
NULL,
NULL,
hInstance,
NULL );
if (!hWndMain)
return FALSE;
if (!minit ())
{
DestroyWindow(hWndMain);
return 0;
}
ShowWindow (hWndMain, SW_NORMAL);
UpdateWindow (hWndMain);
BringWindowToTop (hWndMain);
SetFocus (hWndMain);
PR_AppActive = TRUE;
PR_MouseSyncAcquire (hWndMain);
return TRUE;
} /* initApplication */
/*
* WinMain
*/
int PASCAL WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow )
{
LPSTR realcommand;
if( !initApplication(hInstance, nCmdShow) )
return FALSE;
{
int argc;
char **argv;
#ifdef __WATCOMC__
extern int WatMain(int argc, char **argv);
#else
extern int main(int argc, char **argv);
#endif
realcommand = GetCommandLine ();
argv = commandLineToArgv(realcommand, &argc);
// PRGUI_InitPath (argv[0]);
#ifdef __WATCOMC__
WatMain (argc, argv);
#else
main (argc, argv);
#endif
}
mdeinit ();
DestroyWindow(hWndMain);
return 0;
} /* WinMain */
/*
* Converts lpCmdLine to WinMain into argc, argv
*/
static char *argvbuf[32];
static char cmdLineBuffer[1024];
char **
commandLineToArgv(LPSTR lpCmdLine, int *pArgc)
{
char *p, *pEnd;
int argc = 0;
if (lpCmdLine == NULL) {
*pArgc = argc;
return argvbuf;
}
strcpy(cmdLineBuffer, lpCmdLine);
p = cmdLineBuffer;
pEnd = p + strlen(cmdLineBuffer);
if (pEnd >= &cmdLineBuffer[1022]) pEnd = &cmdLineBuffer[1022];
fflush (stdout);
while (1) {
/* skip over white space */
fflush(stdout);
while (*p == ' ') p++;
if (p >= pEnd) break;
while (*p == '\"') p++;
if (p >= pEnd) break;
argvbuf[argc++] = p;
if (argc >= 32) break;
/* skip till there's a 0 or a white space */
while (*p && (*p != ' ')) p++;
if (*p == ' ') *p++ = 0;
if (*p == '\"') *p++ = 0;
}
*pArgc = argc;
return argvbuf;
}
void getWindowSize(float *width, float *height)
{
RECT rect;
GetClientRect(hWndMain, &rect);
*width = (float) rect.right;
*height = (float) rect.bottom;
}
/* This dispatches any messages waiting and
waits in a loop if the application is not active. */
void UpdateMessages (void)
{
MSG msg;
PR_ReadMouse ();
PR_ReadKeyboard ();
do {
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
} while (!PR_AppActive);
}
char PR_getch (void)
{
MSG msg;
char rv;
if (keytail != keyhead)
{
rv = keyqueue[keytail++];
keytail &= 255;
return rv;
}
while (GetMessage( &msg, NULL, 0, 0 ))
{
TranslateMessage (&msg);
DispatchMessage (&msg);
if (keytail != keyhead)
{
rv = keyqueue[keytail++];
keytail &= 255;
return rv;
}
}
return rv;
}
int PR_kbhit (void)
{
MSG msg;
if (keyhead != keytail)
return 1;
while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage (&msg);
DispatchMessage (&msg); /* this might change keyhead */
if (keyhead != keytail)
return 1;
}
return 0;
}